/**
 * @file .
 * @author wangxiaowei <wangxiaowei0303@163.com>
 * @date 2015-05-28 01:02
 */
#include <math.h>
#include <string.h>

#include <algorithm>
#include <opencv2/core/core.hpp>

#include "HistUtil.h"

void
HistUtil::calc(const cv::Mat &img,unsigned int *hist)
{
    const size_t histNum = IMG_GRAY_VAL_MAX + 1;
    memset(hist,0,sizeof(unsigned int) * histNum);
    cv::MatConstIterator_<uchar> iter = img.begin<uchar>();
    cv::MatConstIterator_<uchar> end = img.end<uchar>();
    for (; iter != end; ++iter) 
        ++hist[*iter];
    return ;
}

cv::Mat
HistUtil::draw(const unsigned int *hist,unsigned int pph,
    unsigned int h,unsigned int histNum)
{
    /*
     * BACKGROUND,背景色,默认为白色.
     * FOREGROUND,前景色,即在绘制柱体时采用的颜色,默认为黑色.
     */
    enum {
        BACKGROUND = IMG_GRAY_VAL_MIN,
        FOREGROUND = IMG_GRAY_VAL_MAX
    };

    unsigned int w = pph * histNum;
    if (h == 0)
        h = w;
    cv::Mat mat(h,w,CV_8UC1,cv::Scalar(BACKGROUND));

    double histMax = *std::max_element(hist,hist + histNum);
    unsigned int histHeight = 0;
    unsigned int histx = 0;/* 在绘制下一柱时,下一柱在 x 轴的起始坐标  */
    for (size_t i = 0; i < histNum; ++i) {
        histHeight = round(hist[i] / histMax * h);
        mat(cv::Range(h - histHeight,h),
            cv::Range(histx,histx + pph)) = cv::Scalar(FOREGROUND);
        histx += pph;
    }
    return mat;
}

